(ns statistic.KullbackLeibler)

(defn sumUpValues [statistic]
  (reduce #(+ %1 (val %2)) 0  statistic))

(defn getPropabilities [statistic]
  (let [maxValue (sumUpValues statistic)]
    (reduce #(assoc %1 (key %2) (/ (val %2) maxValue)) {}  statistic)))

(defn log2 [n]
  (/ (Math/log n) (Math/log 2)))

(defn prop-times-log [key propMap1 propMap2]
  (* (get propMap1 key 1/9223372036854775807)
     (rationalize 
       (log2 
         (/ (get propMap1 key 1/9223372036854775807) 
            (get propMap2 key 1/9223372036854775807))))))

(defn Dkl [listP listQ]
  (let [probabilities_P (getPropabilities listP)
        probabilities_Q (getPropabilities listQ)]
    (reduce #(+ %1
                (prop-times-log (key %2 ) probabilities_P probabilities_Q))
            0 listP)))

(defn equalDistribution [x]
  (zipmap (range 1 (+ 1 x)) (repeat 1)))

(def jahr_1983 {"CDU" 244 "SPD" 193 "FDP" 34 "Die Grünen" 27})
(def jahr_2005 {"CDU" 226 "SPD" 222 "FDP" 61 "Die Linke" 54 "Die Grünen" 51})
(def jahr_2009 {"CDU" 239 "SPD" 146 "FDP" 93 "Die Linke" 76 "Die Grünen" 68})

(def prop_1983 (getPropabilities jahr_1983))
(def prop_2005 (getPropabilities jahr_2005))
(def prop_2009 (getPropabilities jahr_2009))

(def L_0 (equalDistribution 49))
(def lotto-statistik {1 445 2 456 3 458 4 456 5 447 6 490 7 452
                      8 421 9 458 10 453 11 467 12 428 13 389 14 435
                      15 428 16 434 17 458 18 435 19 440 20 432 21 429
                      22 470 23 436 24 449 25 461 26 482 27 461 28 421
                      29 436 30 422 31 469 32 494 33 476 34 444 35 442
                      36 456 37 444 38 475 39 451 40 452 41 458 42 456
                      43 473 44 432 45 411 46 426 47 439 48 451 49 498 })
